package DispatchSys;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import Shared.MapPosition;
import Shared.MsgType;
import Shared.RadioManager;
import Shared.RadioMessage;

/**
 * The RadioSoftware module, see Architecture report for specifications.
 */

public class RadioSoftware {

	private RadioManager rm;
	private BlockingQueue<RadioMessage> receivingQueue = new LinkedBlockingQueue<RadioMessage>();

	private static final RadioSoftware singleton = new RadioSoftware();

	/**
	 * @return the unique RadioSoftware instance.
	 */
	public static RadioSoftware getInstance() {
		return singleton;
	}

	private RadioSoftware() {
		this.rm = RadioManager.getInstance();
	}

	/**
	 * Sends a message to an ambulance of the real world.
	 * 
	 * @param messageType
	 *            The message type to send
	 * @param ambulanceID
	 *            The receiving ambulance ID
	 * @return true if correctly sent.
	 */
	public boolean send(MsgType messageType, int ambulanceID) {
		return this.rm.sendToWorld(new RadioMessage(messageType, ambulanceID));
	}

	/**
	 * Sends a message containing a position to an ambulance of the real world.
	 * 
	 * @param position
	 *            The position to send
	 * @param ambulanceID
	 *            The receiving ambulance ID
	 * @return true if correctly sent, false otherwise.
	 */
	public boolean send(MapPosition position, int ambulanceID) {
		return this.rm.sendToWorld(new RadioMessage(position, ambulanceID));
	}

	/**
	 * Called by the RadioManager when a Radio message was send to the software.
	 * 
	 * @param message
	 *            the received message
	 * @return true if correctly received, false otherwise.
	 */
	public boolean receive(RadioMessage message) {
		return receivingQueue.add(message);
	}

	/**
	 * Return the oldest unread RadioMessage received. Blocks until at least one
	 * unread RadioMessage exists.
	 * 
	 * @return The received RadioMessage.
	 * @throws InterruptedException
	 */
	public RadioMessage listen() throws InterruptedException {
		return receivingQueue.take();
	}

}
